import React, { createContext, useContext, useEffect, useState, useRef, useCallback } from 'react';
import type { MessageInstance } from 'antd/es/message/interface';

// 定义访问日志的数据结构
export interface AccessLog {
    id: number;
    user: string;
    device: string;
    device_id: string;
    timestamp: string;
    is_success: boolean;
    snapshot_path: string;
    user_avatar: string | null;
}

// 定义Context中共享的数据和方法
interface UserWebSocketContextType {
    logs: AccessLog[];
    isConnected: boolean;
    error: string | null;
}

// 创建Context
const UserWebSocketContext = createContext<UserWebSocketContextType | undefined>(undefined);

// 创建一个自定义Hook，方便子组件使用Context
export const useUserWebSocket = () => {
    const context = useContext(UserWebSocketContext);
    if (!context) {
        throw new Error('useUserWebSocket must be used within a UserWebSocketProvider');
    }
    return context;
};

// WebSocket Provider组件
interface UserWebSocketProviderProps {
    children: React.ReactNode;
    messageApi: MessageInstance;
}

export const UserWebSocketProvider: React.FC<UserWebSocketProviderProps> = ({ children, messageApi }) => {
    const [logs, setLogs] = useState<AccessLog[]>([]);
    const [isConnected, setIsConnected] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const socketRef = useRef<WebSocket | null>(null);

    const connect = useCallback(() => {
        const token = localStorage.getItem('authToken'); // 使用普通用户的token
        if (!token) {
            console.error("UserWebSocket: No auth token found.");
            setError("User token not found. Cannot connect to WebSocket.");
            return;
        }

        // 根据环境确定协议
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
        // 连接到用户专属的dashboard端点
        const wsUrl = `${protocol}//${window.location.host}/ws/user/dashboard/?token=${token}`;

        console.log("UserWebSocket: Attempting to connect to", wsUrl);

        const socket = new WebSocket(wsUrl);
        socketRef.current = socket;

        socket.onopen = () => {
            console.log("UserWebSocket: Connection established.");
            setIsConnected(true);
            setError(null);
            messageApi.success('已连接到实时日志服务', 2);

            // 连接成功后，请求历史日志
            socket.send(JSON.stringify({ command: 'get_my_logs' }));
        };

        socket.onmessage = (event) => {
            const data = JSON.parse(event.data);
            console.log("UserWebSocket: Received message:", data);

            switch (data.type) {
                case 'user_logs': // 初始日志列表
                    setLogs(data.logs || []);
                    break;
                case 'new_access_log': // 接收单条新日志
                    setLogs(prevLogs => {
                        // 检查新日志的ID是否已存在于当前列表中
                        const isDuplicate = prevLogs.some(log => log.id === data.payload.id);
                        if (isDuplicate) {
                            // 如果是重复的，则不更新状态，直接返回旧的日志列表
                            console.warn(`UserWebSocket: Duplicate log received with ID: ${data.payload.id}. Ignoring.`);
                            return prevLogs;
                        }
                        // 如果不是重复的，则添加到列表顶部
                        return [data.payload, ...prevLogs].slice(0, 100);
                    });
                    break;
                case 'error':
                    messageApi.error(`服务器错误: ${data.message}`);
                    break;
                default:
                    console.warn("UserWebSocket: Received unknown message type:", data.type);
            }
        };

        socket.onclose = (event) => {
            console.log("UserWebSocket: Connection closed.", event);
            setIsConnected(false);
            if (event.code !== 1000) { // 1000是正常关闭
                setError(`WebSocket disconnected with code: ${event.code}. Reconnecting...`);
                setTimeout(connect, 5000); // 尝试重连
            }
        };

        socket.onerror = (err) => {
            console.error("UserWebSocket: Error occurred:", err);
            setError("An error occurred with the WebSocket connection.");
            socket.close();
        };

    }, [messageApi]);

    useEffect(() => {
        connect();
        return () => {
            if (socketRef.current) {
                console.log("UserWebSocket: Closing connection on component unmount.");
                socketRef.current.close(1000); // 正常关闭
            }
        };
    }, [connect]);

    const value = {
        logs,
        isConnected,
        error,
    };

    return (
        <UserWebSocketContext.Provider value={value}>
            {children}
        </UserWebSocketContext.Provider>
    );
};